<!DOCTYPE HTML>
<html lang="en" class="light sidebar-visible" dir="ltr">
    <head>
        <!-- Book generated using mdBook -->
        <meta charset="UTF-8">
        <title>Kenny Kerr</title>
        <meta name="robots" content="noindex">


        <!-- Custom HTML head -->
        <meta property="og:image" content="https://kennykerr.ca/image.jpg"/>

        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="theme-color" content="#ffffff">

        <link rel="icon" href="favicon.svg">
        <link rel="stylesheet" href="css/variables.css">
        <link rel="stylesheet" href="css/general.css">
        <link rel="stylesheet" href="css/chrome.css">
        <link rel="stylesheet" href="css/print.css" media="print">

        <!-- Fonts -->
        <link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
        <link rel="stylesheet" href="fonts/fonts.css">

        <!-- Highlight.js Stylesheets -->
        <link rel="stylesheet" id="highlight-css" href="highlight.css">
        <link rel="stylesheet" id="tomorrow-night-css" href="tomorrow-night.css">
        <link rel="stylesheet" id="ayu-highlight-css" href="ayu-highlight.css">

        <!-- Custom theme stylesheets -->


        <!-- Provide site root and default themes to javascript -->
        <script>
            const path_to_root = "";
            const default_light_theme = "light";
            const default_dark_theme = "navy";
        </script>
        <!-- Start loading toc.js asap -->
        <script src="toc.js"></script>
    </head>
    <body>
    <div id="mdbook-help-container">
        <div id="mdbook-help-popup">
            <h2 class="mdbook-help-title">Keyboard shortcuts</h2>
            <div>
                <p>Press <kbd>←</kbd> or <kbd>→</kbd> to navigate between chapters</p>
                <p>Press <kbd>S</kbd> or <kbd>/</kbd> to search in the book</p>
                <p>Press <kbd>?</kbd> to show this help</p>
                <p>Press <kbd>Esc</kbd> to hide this help</p>
            </div>
        </div>
    </div>
    <div id="body-container">
        <!-- Work around some values being stored in localStorage wrapped in quotes -->
        <script>
            try {
                let theme = localStorage.getItem('mdbook-theme');
                let sidebar = localStorage.getItem('mdbook-sidebar');

                if (theme.startsWith('"') && theme.endsWith('"')) {
                    localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
                }

                if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
                    localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
                }
            } catch (e) { }
        </script>

        <!-- Set the theme before any content is loaded, prevents flash -->
        <script>
            const default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? default_dark_theme : default_light_theme;
            let theme;
            try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
            if (theme === null || theme === undefined) { theme = default_theme; }
            const html = document.documentElement;
            html.classList.remove('light')
            html.classList.add(theme);
            html.classList.add("js");
        </script>

        <input type="checkbox" id="sidebar-toggle-anchor" class="hidden">

        <!-- Hide / unhide sidebar before it is displayed -->
        <script>
            let sidebar = null;
            const sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
            if (document.body.clientWidth >= 1080) {
                try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
                sidebar = sidebar || 'visible';
            } else {
                sidebar = 'hidden';
            }
            sidebar_toggle.checked = sidebar === 'visible';
            html.classList.remove('sidebar-visible');
            html.classList.add("sidebar-" + sidebar);
        </script>

        <nav id="sidebar" class="sidebar" aria-label="Table of contents">
            <!-- populated by js -->
            <mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
            <noscript>
                <iframe class="sidebar-iframe-outer" src="toc.html"></iframe>
            </noscript>
            <div id="sidebar-resize-handle" class="sidebar-resize-handle">
                <div class="sidebar-resize-indicator"></div>
            </div>
        </nav>

        <div id="page-wrapper" class="page-wrapper">

            <div class="page">
                <div id="menu-bar-hover-placeholder"></div>
                <div id="menu-bar" class="menu-bar sticky">
                    <div class="left-buttons">
                        <label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
                            <i class="fa fa-bars"></i>
                        </label>
                        <button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
                            <i class="fa fa-paint-brush"></i>
                        </button>
                        <ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
                            <li role="none"><button role="menuitem" class="theme" id="default_theme">Auto</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
                        </ul>
                        <button id="search-toggle" class="icon-button" type="button" title="Search (`/`)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="/ s" aria-controls="searchbar">
                            <i class="fa fa-search"></i>
                        </button>
                    </div>

                    <h1 class="menu-title">Kenny Kerr</h1>

                    <div class="right-buttons">
                        <a href="print.html" title="Print this book" aria-label="Print this book">
                            <i id="print-button" class="fa fa-print"></i>
                        </a>
                        <a href="https://github.com/kennykerr/blog" title="Git repository" aria-label="Git repository">
                            <i id="git-repository-button" class="fa fa-github"></i>
                        </a>

                    </div>
                </div>

                <div id="search-wrapper" class="hidden">
                    <form id="searchbar-outer" class="searchbar-outer">
                        <input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
                    </form>
                    <div id="searchresults-outer" class="searchresults-outer hidden">
                        <div id="searchresults-header" class="searchresults-header"></div>
                        <ul id="searchresults">
                        </ul>
                    </div>
                </div>

                <!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
                <script>
                    document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
                    document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
                    Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
                        link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
                    });
                </script>

                <div id="content" class="content">
                    <main>
                        <p>Kenny Kerr is a Software Engineer at Microsoft where he works on C++ and Rust tools and libraries for the Windows operating system. He is the creator of <a href="https://github.com/microsoft/cppwinrt">C++/WinRT</a> and <a href="https://github.com/microsoft/windows-rs">Rust for Windows</a>. Kenny also wrote recurring columns and feature articles for C/C++ Users Journal, Visual Studio Magazine, MSDN Magazine, originally called Microsoft Systems Journal.</p>
<p><a href="rust-getting-started">Getting Started with Rust</a></p>
<p><a href="https://www.pluralsight.com/authors/kenny-kerr">Kenny's courses on Pluralsight</a></p>
<p><a href="https://github.com/kennykerr">Kenny on GitHub</a></p>
<p><a href="https://www.youtube.com/@kennykerrca/videos">Kenny on YouTube</a></p>
<p><a href="https://www.linkedin.com/in/kennykerr/">Kenny on LinkedIn</a></p>
<p><a href="https://kennykerrca.wordpress.com/">Kenny's old blog on WordPress</a></p>
<p><a href="https://weblogs.asp.net/kennykerr">Kenny's old blog on asp.net</a></p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="getting-started-with-rust"><a class="header" href="#getting-started-with-rust">Getting Started with Rust</a></h1>
<p>The <a href="https://github.com/microsoft/windows-rs">windows-rs</a> project has been available for some time and while I still have a great deal of work left to do, I thought I should start spending some time writing about Rust for Windows and not simply building Rust for Windows. 😊 As I did for <a href="https://github.com/microsoft/cppwinrt">C++/WinRT</a>, I thought I would start writing a few short "how to" or "how it works" articles to help developers understand some of the fundamentals of the <a href="https://github.com/microsoft/windows-rs">windows-rs</a> project.</p>
<p>Some of these topics will be obvious for Rust developers but perhaps not the Windows developer new to Rust. Other topics might be obvious to Windows developers but less so to the seasoned Rust developer new to Windows. Either way, I hope you find it useful. Feel free to <a href="https://github.com/microsoft/windows-rs/issues">open an issue on the repo</a> if you have any questions.</p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="choosing-between-the-windows-and-windows-sys-crates"><a class="header" href="#choosing-between-the-windows-and-windows-sys-crates">Choosing between the windows and windows-sys crates</a></h1>
<p>The <a href="https://crates.io/crates/windows">windows</a> crate provides bindings for the Windows API, including C-style APIs like <code>CreateThreadpool</code> as well as COM and WinRT APIs like DirectX. This crate provides the most comprehensive API coverage for the Windows operating system. Where possible, the <code>windows</code> crate also attempts to provide a more idiomatic and safe programming model for Rust developers.</p>
<p>The <a href="https://crates.io/crates/windows-sys">windows-sys</a> crate provides raw bindings for the C-style Windows APIs. It lacks support for COM and WinRT APIs. The <code>windows-sys</code> crate was born out of the realization that the most expensive aspect of the <code>windows</code> crate, in terms of build time, is the cost of compiling function bodies. The Rust compiler just spends a great deal of effort compiling function bodies, so a version of the <code>windows</code> crate that only includes declarations is both much smaller and faster by comparison. The trouble is that COM-style virtual function calls require extra code gen in Rust (unlike C++) and this in turn leads to slower compile times. Enter the <code>windows-sys</code> crate.</p>
<p>Of course, we continue to work hard at improving performance both in terms of the underlying Rust compiler toolchain as well as the efficiency of the code generated for these crates. We are thus confident that the compile-time will continue to improve.</p>
<div class="table-wrapper"><table><thead><tr><th>What do you need?</th><th><code>windows</code></th><th><code>windows-sys</code></th></tr></thead><tbody>
<tr><td>Fast compile times are one of your top concerns</td><td></td><td>✅</td></tr>
<tr><td>You need <code>no_std</code> support</td><td></td><td>✅</td></tr>
<tr><td>You need COM or WinRT support</td><td>✅</td><td></td></tr>
<tr><td>You would prefer to use APIs that feel idiomatic to Rust</td><td>✅</td><td></td></tr>
<tr><td>Minimum supported Rust version</td><td>1.56</td><td>1.56</td></tr>
</tbody></table>
</div><div style="break-before: page; page-break-before: always;"></div><h1 id="how-are-these-crates-built"><a class="header" href="#how-are-these-crates-built">How are these crates built?</a></h1>
<p>The <a href="https://crates.io/crates/windows">windows</a> and <a href="https://crates.io/crates/windows-sys">windows-sys</a> crates are generated from metadata describing the Windows API. Originally only WinRT APIs included metadata, but metadata is now provided for older C and COM APIs as well. The <a href="https://github.com/microsoft/win32metadata/">win32metadata</a> project provides the tools to produce the metadata and the <a href="https://crates.io/crates/windows-metadata">windows-metadata</a> and <a href="https://crates.io/crates/windows-bindgen">windows-bindgen</a> crates are used to read the metadata and generate the <code>windows</code> and <code>windows-sys</code> crates. The bindings are generated differently based on the differing goals of the respective crates. You can find the exact metadata files used to generate a particular version of the <code>windows</code> and <code>windows-sys</code> crates <a href="https://github.com/microsoft/windows-rs/tree/master/crates/libs/bindgen/default">here</a>.</p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="how-do-i-find-a-particular-api"><a class="header" href="#how-do-i-find-a-particular-api">How do I find a particular API?</a></h1>
<p>First <a href="rust-getting-started/windows-or-windows-sys.html">pick the crate you would like to use</a>. Then search the documentation for the chosen crate:</p>
<ul>
<li>
<p><a href="https://microsoft.github.io/windows-docs-rs/">windows</a></p>
</li>
<li>
<p><a href="https://docs.rs/windows-sys">windows-sys</a></p>
</li>
</ul>
<p>Note that the docs include a note indicating which features to enable in order to access a particular API.</p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="what-apis-are-included"><a class="header" href="#what-apis-are-included">What APIs are included?</a></h1>
<p>All Windows APIs provided by the Windows SDK are included, with a few exceptions. The definitions of these APIs are collected from <a href="rust-getting-started/how-are-crates-built.html">metadata and transformed into Rust bindings</a>. The process of generating the Rust bindings purposefully omits a few APIs. APIs are only excluded if they are (1) unsuitable for Rust developers and (2) impose a large hit on the overall size of the <a href="https://crates.io/crates/windows">windows</a> and <a href="https://crates.io/crates/windows-sys">windows-sys</a> crates.</p>
<p>The Xaml API is excluded because it is all but unusable without direct language support that only the Xaml team can provide. Xaml is also focused and tailored for C# app development so this API isn't applicable to Rust developers. The MsHtml API is also excluded because it is only intended for Microsoft's older scripting languages like JScript and VBScript. It is also by far the single largest module as measured in lines of code. Beyond that, a few deprecrated and unusable APIs are excluded. You can see exactly what the <a href="https://github.com/microsoft/windows-rs/blob/59950e2e2b7bd79f2de2020ee33745d7f642230f/crates/tools/windows/src/main.rs#L4-L5">windows crate excludes</a> and what the <a href="https://github.com/microsoft/windows-rs/blob/59950e2e2b7bd79f2de2020ee33745d7f642230f/crates/tools/sys/src/main.rs#L5-L35">windows-sys crate excludes</a>.</p>
<p>Beyond that, the <code>windows-sys</code> crate currently excludes all COM and WinRT APIs. The <code>windows-sys</code> crate only includes declarations and COM and WinRT calls are far too cumbersome without the abstractions provided by the windows crate. Here are some tips for <a href="rust-getting-started/windows-or-windows-sys.html">choosing between the windows and windows-sys crates</a>.</p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="wheres-my-favorite-macro-from-the-windows-sdk"><a class="header" href="#wheres-my-favorite-macro-from-the-windows-sdk">Where's my favorite macro from the Windows SDK?</a></h1>
<p>The <a href="https://crates.io/crates/windows">windows</a> and <a href="https://crates.io/crates/windows-sys">windows-sys</a> crates are <a href="rust-getting-started/how-are-crates-built.html">generated from metadata</a>. This metadata only includes type definitions and function signatures, not macros, header-only functions, or function bodies. You may find some equivalents of common C/C++ helper macros and functions in the <code>windows</code> crate, but in general the macros don't have direct equivalents in the <code>windows</code> or <code>windows-sys</code> crates.</p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="calling-your-first-api-with-the-windows-crate"><a class="header" href="#calling-your-first-api-with-the-windows-crate">Calling your first API with the windows crate</a></h1>
<p>So you want to get a feel for calling a simple Windows API. Where to start? Let's look at a relatively simple API for submitting callbacks to the thread pool. You can read <a href="https://learn.microsoft.com/en-us/archive/msdn-magazine/2011/august/windows-with-c-the-windows-thread-pool-and-work">more about this API here</a>.</p>
<p>The first step is to add a dependency on the <a href="https://crates.io/crates/windows">windows</a> crate and indicate which features you'd like to access:</p>
<pre><code class="language-toml">[dependencies.windows]
version = "0.52"
features = [
    "Win32_Foundation",
    "Win32_System_Threading",
]
</code></pre>
<p>Why these two features? Well, the thread pool API is defined in the <code>Win32::System::Threading</code> module and we'll also use a handful of definitions from the <code>Win32::Foundation</code> module. If you're unsure, the docs for any given API provide a helpful comment indicating which features are required. For example, here are the docs for <a href="https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/System/Threading/fn.WaitForThreadpoolWorkCallbacks.html">WaitForThreadpoolWorkCallbacks</a> where you can see it depends on both of these features since it is defined in the <code>Win32::System::Threading</code> module and depends on <code>BOOL</code> which is defined in the <code>Win32::Foundation</code> module.</p>
<p>Cargo will now handle the heavy lifting, tracking down the dependencies and making sure the import libs are present, so that we can simply call these APIs in Rust without any further configuration. We can employ a <code>use</code> declaration to make these APIs a little more accessible:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use windows::{core::Result, Win32::System::Threading::*};
<span class="boring">}</span></code></pre></pre>
<p>In order to "prove" that the code works and yet keep it real simple let's just use the thread pool to increment a counter some number of times. Here we can use a reader-writer lock for safe and multi-threaded access to the counter variable:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>static COUNTER: std::sync::RwLock&lt;i32&gt; = std::sync::RwLock::new(0);
<span class="boring">}</span></code></pre></pre>
<p>For this example, I'll just use a simple <code>main</code> function with a big <code>unsafe</code> block since virtually everything here is going to be <code>unsafe</code>. Why is that? Well the <code>windows</code> crate lets you call foreign functions and these are generally assumed to be <code>unsafe</code>.</p>
<pre><pre class="playground"><code class="language-rust">fn main() -&gt; Result&lt;()&gt; {
    unsafe {
        
    }

    Ok(())
}</code></pre></pre>
<p>The thread pool API is modeled as a set of "objects" exposed via a traditional C-style API. The first thing we need to do is create a work object:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let work = CreateThreadpoolWork(Some(callback), None, None)?;
<span class="boring">}</span></code></pre></pre>
<p>The first parameter is a pointer to a callback function. The remaining parameters are optional and you can read more about them in my thread pool series on MSDN.</p>
<p>The callback itself must be a valid C-style callback according to the signature expected by the thread pool API. Here's a simple callback that will increment the count:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>extern "system" fn callback(_: PTP_CALLBACK_INSTANCE, _: *mut std::ffi::c_void, _: PTP_WORK) {
    let mut counter = COUNTER.write().unwrap();
    *counter += 1;
}
<span class="boring">}</span></code></pre></pre>
<p>The parameters can safely be ignored but do come in handy from time to time. At this point, we have a valid work object but nothing is happening yet. In order to kick off some "work", we need to submit the work object to the thread pool. You can do so as many times as you'd like, so lets go ahead and do it ten times:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>for _ in 0..10 {
    SubmitThreadpoolWork(work);
}
<span class="boring">}</span></code></pre></pre>
<p>You can now expect the callbacks to run concurrently, hence the <code>RwLock</code> above. Of course, with all of that concurrency we need some way to tell when the work is done. That's the job of the <code>WaitForThreadpoolWorkCallbacks</code> function:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>WaitForThreadpoolWorkCallbacks(work, false);
<span class="boring">}</span></code></pre></pre>
<p>The second parameter indicates whether we would like to cancel any pending callbacks that have not started to execute. Passing false here thus indicates that we would like the wait function to block until all of the submitted work has completed. At that point, we can safely close the work object to free its memory:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>CloseThreadpoolWork(work);
<span class="boring">}</span></code></pre></pre>
<p>And just to prove that it works reliably, we can print out the counter's value:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let counter = COUNTER.read().unwrap();
println!("counter: {}", *counter);
<span class="boring">}</span></code></pre></pre>
<p>Running the sample should print something like this:</p>
<pre><code>counter: 10
</code></pre>
<p>Here's the <a href="https://github.com/microsoft/windows-rs/blob/master/crates/samples/windows/thread_pool_work/src/main.rs">full sample for reference</a>.</p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="calling-your-first-api-with-the-windows-sys-crate"><a class="header" href="#calling-your-first-api-with-the-windows-sys-crate">Calling your first API with the windows-sys crate</a></h1>
<p>So you want to get a feel for calling a simple Windows API. Where to start? Let's look at a relatively simple API for submitting callbacks to the thread pool. You can read <a href="https://learn.microsoft.com/en-us/archive/msdn-magazine/2011/august/windows-with-c-the-windows-thread-pool-and-work">more about this API here</a>.</p>
<p>The first step is to add a dependency on the <a href="https://crates.io/crates/windows-sys">windows-sys</a> crate and indicate which features you'd like to access:</p>
<pre><code class="language-toml">[dependencies.windows-sys]
version = "0.52"
features = [
    "Win32_Foundation",
    "Win32_System_Threading",
]
</code></pre>
<p>Why these two features? Well, the thread pool API is defined in the <code>Win32::System::Threading</code> module and we'll also use a handful of definitions from the <code>Win32::Foundation</code> module. If you're unsure, the docs for any given API provide a helpful comment indicating which features are required. For example, here are the docs for <a href="https://docs.rs/windows-sys/latest/windows_sys/Win32/System/Threading/fn.WaitForThreadpoolWorkCallbacks.html">WaitForThreadpoolWorkCallbacks</a> where you can see it depends on both of these features since it is defined in the <code>Win32::System::Threading</code> module and depends on <code>BOOL</code> which is defined in the <code>Win32::Foundation</code> module.</p>
<p>Cargo will now handle the heavy lifting, tracking down the dependencies and making sure the import libs are present, so that we can simply call these APIs in Rust without any further configuration. We can employ a <code>use</code> declaration to make these APIs a little more accessible:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use windows_sys::{Win32::Foundation::*, Win32::System::Threading::*};
<span class="boring">}</span></code></pre></pre>
<p>In order to "prove" that the code works and yet keep it real simple let's just use the thread pool to increment a counter some number of times. Here we can use a reader-writer lock for safe and multi-threaded access to the counter variable:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>static COUNTER: std::sync::RwLock&lt;i32&gt; = std::sync::RwLock::new(0);
<span class="boring">}</span></code></pre></pre>
<p>For this example, I'll just use a simple <code>main</code> function with a big <code>unsafe</code> block since virtually everything here is going to be <code>unsafe</code>. Why is that? Well the <code>windows</code> crate lets you call foreign functions and these are generally assumed to be <code>unsafe</code>.</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
    unsafe {
        
    }
}</code></pre></pre>
<p>The thread pool API is modeled as a set of "objects" exposed via a traditional C-style API. The first thing we need to do is create a work object:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let work = CreateThreadpoolWork(Some(callback), std::ptr::null_mut(), std::ptr::null());
<span class="boring">}</span></code></pre></pre>
<p>The first parameter is a pointer to a callback function. The remaining parameters are optional and you can read more about them in my thread pool series on MSDN.</p>
<p>Since this function allocates memory, it is possible that it might fail, and this is indicated by returning a null pointer rather than a valid work object handle. We'll check for this condition and call the <code>GetLastError</code> function to display any relevant error code:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>if work == 0 {
    println!("{:?}", GetLastError());
    return;
}
<span class="boring">}</span></code></pre></pre>
<p>The callback itself must be a valid C-style callback according to the signature expected by the thread pool API. Here's a simple callback that will increment the count:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>extern "system" fn callback(_: PTP_CALLBACK_INSTANCE, _: *mut std::ffi::c_void, _: PTP_WORK) {
    let mut counter = COUNTER.write().unwrap();
    *counter += 1;
}
<span class="boring">}</span></code></pre></pre>
<p>The parameters can safely be ignored but do come in handy from time to time. At this point, we have a valid work object but nothing is happening yet. In order to kick off some "work", we need to submit the work object to the thread pool. You can do so as many times as you'd like, so lets go ahead and do it ten times:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>for _ in 0..10 {
    SubmitThreadpoolWork(work);
}
<span class="boring">}</span></code></pre></pre>
<p>You can now expect the callbacks to run concurrently, hence the <code>RwLock</code> above. Of course, with all of that concurrency we need some way to tell when the work is done. That's the job of the <code>WaitForThreadpoolWorkCallbacks</code> function:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>WaitForThreadpoolWorkCallbacks(work, 0);
<span class="boring">}</span></code></pre></pre>
<p>The second parameter indicates whether we would like to cancel any pending callbacks that have not started to execute. Passing <code>0</code>, meaning false, here thus indicates that we would like the wait function to block until all of the submitted work has completed. At that point, we can safely close the work object to free its memory:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>CloseThreadpoolWork(work);
<span class="boring">}</span></code></pre></pre>
<p>And just to prove that it works reliably, we can print out the counter's value:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let counter = COUNTER.read().unwrap();
println!("counter: {}", *counter);
<span class="boring">}</span></code></pre></pre>
<p>Running the sample should print something like this:</p>
<pre><code>counter: 10
</code></pre>
<p>Here's the <a href="https://github.com/microsoft/windows-rs/blob/master/crates/samples/windows-sys/thread_pool_work/src/main.rs">full sample for reference</a>.</p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="calling-your-first-com-api"><a class="header" href="#calling-your-first-com-api">Calling your first COM API</a></h1>
<p>COM APIs are unique in that they expose functionality through interfaces. An interface is just a collection of virtual function pointers grouped together in what is known as a vtable, or virtual function table. This is not something that Rust supports directly, like C++ does, but the <a href="https://crates.io/crates/windows">windows</a> crate provides the necessary code gen to make it possible and seamless. A COM API will still typically start life through a traditional C-style function call in order to get your hands on a COM interface. From there you might call other methods via the interface.</p>
<p>Some COM-based APIs can get real complicated so let's start with a very simple example. The <code>CreateUri</code> function is <a href="https://learn.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/ms775098(v=vs.85)">officially documented on MSDN</a> as returning the <code>IUri</code> interface representing the results of parsing the given URI. The Rust <a href="https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/System/Com/fn.CreateUri.html">docs for the windows crate</a> indicate that it resides in the <code>Win32::System::Com</code> module so we can configure our <code>windows</code> crate dependency accordingly:</p>
<pre><code class="language-toml">[dependencies.windows]
version = "0.52"
features = [
    "Win32_System_Com",
]
</code></pre>
<p>And we can employ a <code>use</code> declaration to make this API a little more accessible. The <code>windows</code> crate's <code>core</code> module also provides a few helpers to make it easier to work with COM interfaces, so we'll include that as well:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use windows::{core::*, Win32::System::Com::*};
<span class="boring">}</span></code></pre></pre>
<p>For this example, I'll just use a simple <code>main</code> function with a big <code>unsafe</code> block since virtually everything here is going to be <code>unsafe</code>. Why is that? Well the <code>windows</code> crate lets you call foreign functions and these are generally assumed to be <code>unsafe</code>.</p>
<pre><pre class="playground"><code class="language-rust">fn main() -&gt; Result&lt;()&gt; {
    unsafe {
        
        Ok(())
    }
}</code></pre></pre>
<p>The only "interesting" point here is the use of the <code>Result</code> type from the <code>windows::core</code> module that provides Windows error handling to simplify the following API calls. And with that, we can call the <code>CreateUri</code> function as follows:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let uri = CreateUri(w!("http://kennykerr.ca"), Uri_CREATE_CANONICALIZE, 0)?;
<span class="boring">}</span></code></pre></pre>
<p>There's quite a lot going on here. The first parameter is actually a <code>PCWSTR</code>, representing a null-terminated wide string used by many Windows APIs. The <code>windows</code> crate provides the handy <code>w!</code> macro for creating a valid null-terminated wide string as a compile-time constant. The second parameter is just the default flag specified by the official documentation. The third parameter is reserved and should thus be zero.</p>
<p>The resulting <code>IUri</code> object has various methods that we can now use to inspect the URI. The <a href="https://learn.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/ms775038(v=vs.85)">official documentation</a> describes the various interface methods and <a href="https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/System/Com/struct.IUri.html">the Rust docs</a> give you a quick glimpse at their various signatures so that you can quickly figure out how to call them in Rust. For this example, let's just call two of them to print out the URI's domain and the HTTP port number:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let domain = uri.GetDomain()?;
let port = uri.GetPort()?;

println!("{domain} ({port})");
<span class="boring">}</span></code></pre></pre>
<p>Under the hood, those methods will invoke the virtual functions through the COM interface and into the implementation provided by the API. They also provide a bunch of error and signature transformation to make it very natural to use from Rust. And that's it, running the sample should print something like this:</p>
<pre><code>kennykerr.ca (80)
</code></pre>
<p>Here's the <a href="https://github.com/microsoft/windows-rs/blob/master/crates/samples/windows/com_uri/src/main.rs">full sample for reference</a>.</p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="calling-your-first-winrt-api"><a class="header" href="#calling-your-first-winrt-api">Calling your first WinRT API</a></h1>
<p>Windows 8 introduced the Windows Runtime, which at its heart, is just COM with a few more conventions thrown in to make language bindings appear more seamless. The <a href="https://crates.io/crates/windows">windows</a> crate already makes calling COM APIs far more seamless than it is for C++ developers, but WinRT goes further by providing first-class support for modeling things like constructors, events, and class hierarchies. In <a href="rust-getting-started/calling-your-first-com-api.html">calling your first COM API</a>, we saw that you still had to bootstrap the API with a C-style DLL export before calling COM interface methods. WinRT works the same way but abstracts this away in a generalized manner.</p>
<p>Let's use a simple example to illustrate. The <code>XmlDocument</code> "class" models an XML document that can be loaded from various sources. The Rust <a href="https://microsoft.github.io/windows-docs-rs/doc/windows/Data/Xml/Dom/struct.XmlDocument.html">docs for the windows crate</a> indicate that this type resides in the <code>Data::Xml::Dom</code> module so we can configure our <code>windows</code> crate dependency as follows:</p>
<pre><code class="language-toml">[dependencies.windows]
version = "0.52" 
features = [
    "Data_Xml_Dom",
]
</code></pre>
<p>And we can employ a <code>use</code> declaration to make this API a little more accessible. The <code>windows</code> crate's <code>core</code> module just provides a few helpers to make it easier to work with Windows APIs, so we'll include that as well:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use windows::{core::*, Data::Xml::Dom::XmlDocument}; 
<span class="boring">}</span></code></pre></pre>
<p>For this example, I'll just use a simple <code>main</code> function with a <code>Result</code> type from the <code>windows::core</code> module to provide automatic error propagation and simplify the subsequent API calls:</p>
<pre><pre class="playground"><code class="language-rust">fn main() -&gt; Result&lt;()&gt; {

    Ok(())
}</code></pre></pre>
<p>Unlike the previous Win32 and COM examples, you'll notice that this <code>main</code> function does not need an <code>unsafe</code> block since WinRT calls are assumed to be safe thanks to its more constrained type-system.</p>
<p>To begin, we can simply call the <code>new</code> method to create a new <code>XmlDocument</code> object:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let doc = XmlDocument::new()?;
<span class="boring">}</span></code></pre></pre>
<p>This looks a lot more like an idiomatic Rust type than your typical COM API, but under the hood a similar mechanism is used to instantiate the <code>XmlDocument</code> implementation via a DLL export. We can then call the <code>LoadXml</code> method to test it out. There are various other options for loading XML from different sources, which you can <a href="https://learn.microsoft.com/en-us/uwp/api/windows.data.xml.dom.xmldocument?view=winrt-22621">read about in the official documentation</a> or from the Rust docs for the <code>XmlDocument</code> API. The <code>windows</code> crate also provides the handy <code>h!</code> macro for creating an <code>HSTRING</code>, the string type used by WinRT APIs:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>doc.LoadXml(h!("&lt;html&gt;hello world&lt;/html&gt;"))?;
<span class="boring">}</span></code></pre></pre>
<p>And just like that, we have a fully-formed Xml document that we can inspect. For this example, let's just grab the document element and then do some basic queries as follows:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let root = doc.DocumentElement()?;
assert!(root.NodeName()? == "html");
println!("{}", root.InnerText()?);
<span class="boring">}</span></code></pre></pre>
<p>First we assert that the element's name is in fact "html" and then print out the element's inner text. As with the previous COM example, those methods all invoke virtual functions through COM interfaces, but the <code>windows</code> crate makes it very simple to make such calls directly from Rust. And that's it. Running the sample should print something like this:</p>
<pre><code>hello world
</code></pre>
<p>Here's the <a href="https://github.com/microsoft/windows-rs/blob/master/crates/samples/windows/xml/src/main.rs">full sample for reference</a>.</p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="how-do-i-query-for-a-specific-com-interface"><a class="header" href="#how-do-i-query-for-a-specific-com-interface">How do I query for a specific COM interface?</a></h1>
<p>COM and WinRT interfaces in the <a href="https://crates.io/crates/windows">windows</a> crate implement the <a href="https://microsoft.github.io/windows-docs-rs/doc/windows/core/trait.ComInterface.html">ComInterface</a> trait. This trait provides the <code>cast</code> method that will use <code>QueryInterface</code> under the hood to cast the current interface to another interface supported by the object. The <code>cast</code> method returns a <code>Result&lt;T&gt;</code> so that failure can be handled in a natural way in Rust.</p>
<p>For example, it is often necesary to get the <code>IDXGIDevice</code> interface for a given Direct3D device to interop with other rendering APIs. This is how you might create a swap chain for drawing and presenting to a Direct3D device. Let's imagine a simple function that accepts a Direct3D device and returns the underlying DXGI factory:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>fn get_dxgi_factory(device: &amp;ID3D11Device) -&gt; Result&lt;IDXGIFactory2&gt; {
}
<span class="boring">}</span></code></pre></pre>
<p>The first thing you need to do is query or cast the Direct3D device for its DXGI interface as follows:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let device = device.cast::&lt;IDXGIDevice&gt;()?;
<span class="boring">}</span></code></pre></pre>
<p>If its more convenient, you can also make use of type inference as follows:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let device: IDXGIDevice = device.cast()?;
<span class="boring">}</span></code></pre></pre>
<p>With the COM interface in hand, we need an <code>unsafe</code> block to call its methods:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>unsafe {
}
<span class="boring">}</span></code></pre></pre>
<p>Within the <code>unsafe</code> block, we can retrieve the device's physical adapter:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let adapter = device.GetAdapter()?;
<span class="boring">}</span></code></pre></pre>
<p>And just for fun (or debugging), we might print out the adapter's name:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>if cfg!(debug_assertions) {
    let mut desc = Default::default();
    adapter.GetDesc(&amp;mut desc)?;
    println!("{}", String::from_utf16_lossy(&amp;desc.Description));
}
<span class="boring">}</span></code></pre></pre>
<p>Finally, we can return the adapter's parent and also the DXGI factory object for the device:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>adapter.GetParent()
<span class="boring">}</span></code></pre></pre>
<p>Running the sample I get the following impressive results:</p>
<pre><code>AMD FirePro W4100
</code></pre>
<p>Here's a <a href="https://github.com/microsoft/windows-rs/tree/master/crates/samples/windows/direct2d">more comprehensive DirectX example</a>.</p>
<p>The <code>cast</code> method works equally well for WinRT classes and interfaces. It is particularly useful for <a href="https://github.com/microsoft/windows-rs/blob/master/crates/samples/windows/uiautomation/src/main.rs">interop with WinRT APIs</a>.</p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="how-do-i-implement-an-existing-com-interface"><a class="header" href="#how-do-i-implement-an-existing-com-interface">How do I implement an existing COM interface?</a></h1>
<p>In some cases, you may need to implement an existing COM interface rather than simply calling an existing implementation provided by the operating system. This is where the <code>implement</code> feature and macro come in handy. The <a href="https://crates.io/crates/windows">windows</a> crate provides optional implementation support hidden behind the <code>implement</code> feature. Once enabled, the <a href="https://docs.rs/windows-implement/latest/windows_implement/attr.implement.html">implement</a> macro may be used to implement any number of COM interfaces. The macro takes care of implementing <code>IUnknown</code> itself.</p>
<p>Let's implement a simple interface defined by Windows to illustrate. The <code>IPersist</code> interface is defined in the <code>Win32::System::Com</code> module, so we'll start by adding a dependency on the <code>windows</code> crate and include the <code>Win32_System_Com</code> feature:</p>
<pre><code class="language-toml">[dependencies.windows]
version = "0.52"
features = [
    "implement",
    "Win32_System_Com",
]
</code></pre>
<p>The <code>implement</code> feature unlocks the implementation support.</p>
<p>The <code>implement</code> macro is included by the <code>windows::core</code> module so we'll keep things simple by including it all as follows:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use windows::{core::*, Win32::System::Com::*};
<span class="boring">}</span></code></pre></pre>
<p>Now its time for the implementation:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>#[implement(IPersist)]
struct Persist(GUID);
<span class="boring">}</span></code></pre></pre>
<p>The <code>implement</code> macro will provide the necessary implementation for the <code>IUnknown</code> interface's lifetime management and interface discovery for whatever interfaces are included in the attribute. In this case, only <code>IPersist</code> is to be implemented.</p>
<p>The implementation itself is defined by a trait that follows the <code>&lt;interface name&gt;_Impl</code> pattern and its up to us to implement it for our implementation as follows:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>impl IPersist_Impl for Persist_Impl {
    fn GetClassID(&amp;self) -&gt; Result&lt;GUID&gt; {
        Ok(self.0)
    }
}
<span class="boring">}</span></code></pre></pre>
<p>The IPersist interface, originally <a href="https://learn.microsoft.com/en-us/windows/win32/api/objidl/nn-objidl-ipersist">documented here</a>, has a single method that returns a <code>GUID</code>, so we'll just implement it by returning the value contained within our implementation. The <code>window</code> crate and <code>implement</code> macro will take care of the rest by providing the actual COM virtual function call and virtual function table layout needed to turn this into a heap-allocated and reference-counted COM object.</p>
<p>All that remains is to move, or box, the implementation into the COM implementation provided by the <code>implement</code> macro through the <code>Into</code> trait:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let guid = GUID::new()?;
let persist: IPersist = Persist(guid).into();
<span class="boring">}</span></code></pre></pre>
<p>At this point, we can simply treat <code>persist</code> as the COM object that it is:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let guid2 = unsafe { persist.GetClassID()? };
assert_eq!(guid, guid2);
println!("{:?}", guid);
<span class="boring">}</span></code></pre></pre>
<p>Here's a <a href="https://github.com/microsoft/windows-rs/tree/master/crates/samples/windows/bits">complete example</a>.</p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="how-do-i-create-stock-collections-for-winrt-collection-interfaces"><a class="header" href="#how-do-i-create-stock-collections-for-winrt-collection-interfaces">How do I create stock collections for WinRT collection interfaces?</a></h1>
<p>Beyond <a href="rust-getting-started/how-to-implement-com-interface.html">implementing COM interfaces</a> yourself, the <a href="https://crates.io/crates/windows">windows</a> crate provides stock collection implementations for common WinRT collection interfaces. Implementing WinRT collection interfaces can be quite challenging, so this should save you a lot of effort in many cases. The <code>implement</code> feature is required to make use of these stock implementations.</p>
<p>Let's consider a few examples. The WinRT collection interfaces are all defined in the <code>Foundation::Collections</code> module, so we'll start by adding a dependency on the <code>windows</code> crate and include the <code>Foundation_Collections</code> feature:</p>
<pre><code class="language-toml">[dependencies.windows]
version = "0.52"
features = [
    "implement",
    "Foundation_Collections",
]
</code></pre>
<p>Creating a collection is as simple as using the <code>TryFrom</code> trait on existing <code>Vec</code> or <code>BTreeMap</code>, depending on the kind of collection:</p>
<div class="table-wrapper"><table><thead><tr><th>WinRT interface</th><th>From</th></tr></thead><tbody>
<tr><td><code>IIterable&lt;T&gt;</code></td><td><code>Vec&lt;T::Default&gt;</code></td></tr>
<tr><td><code>IVectorView&lt;T&gt;</code></td><td><code>Vec&lt;T::Default&gt;</code></td></tr>
<tr><td><code>IMapView&lt;K, V&gt;</code></td><td><code>BTreeMap&lt;K::Default, V::Default&gt;</code></td></tr>
</tbody></table>
</div>
<p>So if you need a <code>IIterable</code> implementation of <code>i32</code> values you can create it as follows:</p>
<pre><pre class="playground"><code class="language-rust">use windows::{core::*, Foundation::Collections::*};

fn main() -&gt; Result&lt;()&gt; {
    let collection = IIterable::&lt;i32&gt;::try_from(vec![1, 2, 3])?;

    for n in collection {
        println!("{n}");
    }

    Ok(())
}</code></pre></pre>
<p>The resulting <code>collection</code> will implement all of the specialized <code>IIterable&lt;i32&gt;</code> methods.</p>
<p>Did you notice the <code>T::Default</code> in the table above? The challenge is that when the WinRT collection contains nullable types, unlike <code>i32</code>, then the collection must necessarily support a backing implementation that support expressing this. The <code>Default</code> associated type just replaces <code>T</code> with <code>Option&lt;T&gt;</code> for such nullable, or reference, types.</p>
<p>Let's consider a slightly more contrived example. Here we'll create an <code>IMapView</code> with strings for keys and interfaces for values. WinRT strings are not nullable but interfaces are. WinRT strings are represented by <code>HSTRING</code> in the <code>windows</code> crate and for the interface we'll just use an <code>IStringable</code> implementation:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use windows::Foundation::*;

#[implement(IStringable)]
struct Value(&amp;'static str);

impl IStringable_Impl for Value {
    fn ToString(&amp;self) -&gt; Result&lt;HSTRING&gt; {
        Ok(self.0.into())
    }
}
<span class="boring">}</span></code></pre></pre>
<p>We can now create a <code>std</code> collection as follows:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::collections::*;

let map = BTreeMap::from([
    ("hello".into(), Some(Value("HELLO").into())),
    ("hello".into(), Some(Value("WORLD").into())),
]);
<span class="boring">}</span></code></pre></pre>
<p>The Rust compiler naturally infers the exact type: <code>BTreeMap&lt;HSTRING, Option&lt;IStringable&gt;&gt;</code>.</p>
<p>Finally, we can wrap that <code>BTreeMap</code> inside a WinRT collection with the <code>TryInto</code> trait as follows:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let map: IMapView&lt;HSTRING, IStringable&gt; = map.try_into()?;

for pair in map {
    println!("{} - {}", pair.Key()?, pair.Value()?.ToString()?);
}
<span class="boring">}</span></code></pre></pre>
<div style="break-before: page; page-break-before: always;"></div><h1 id="understanding-the-windows-targets-crate"><a class="header" href="#understanding-the-windows-targets-crate">Understanding the windows-targets crate</a></h1>
<p>The <a href="https://crates.io/crates/windows">windows</a> and <a href="https://crates.io/crates/windows-sys">windows-sys</a> crates depend on the <a href="https://crates.io/crates/windows-targets">windows-targets</a> crate for linker support. The <code>windows-targets</code> crate includes import libs, supports semantic versioning, and optional support for <code>raw-dylib</code>. It provides explicit import libraries for the following targets:</p>
<ul>
<li>i686_msvc</li>
<li>x86_64_msvc</li>
<li>aarch64_msvc</li>
<li>i686_gnu</li>
<li>x86_64_gnu</li>
<li>x86_64_gnullvm</li>
<li>aarch64_gnullvm</li>
</ul>
<p>An import lib contains information the linker uses to resolve external references to functions exported by DLLs. This allows the operating system to identify a specific DLL and function export at load time. Import libs are both toolchain- and architecture-specific. In other words, different lib files are required depending on whether you're compiling with the MSVC or GNU toolchains and whether you're compiling for the x86 or ARM64 architectures. Note that import libraries don't contain any code, as static libraries do.</p>
<p>While the GNU and MSVC toolchains often provide some import libs to support C++ development, those lib files are often incomplete, missing, or just plain wrong. This can lead to linker errors that are very difficult to diagnose. The <code>windows-targets</code> crate ensures that all functions defined by the <code>windows</code> and <code>windows-sys</code> crates can be linked without relying on implicit lib files distributed by the toolchain. This ensures that dependencies can be managed with Cargo and streamlines cross-compilation. The <code>windows-targets</code> crate also contains version-specific lib file names ensuring semver compatibility. Without this capability, the linker will simply pick the first matching lib file name and fail to resolve any missing or mismatched imports.</p>
<blockquote>
<p><strong>Note</strong>: Ordinarily, you don't need to think about the <code>windows-targets</code> crate at all. The <code>windows</code> and <code>windows-sys</code> crates depend on the <code>windows-targets</code> crate automatically. Only in rare cases will you need to use it directly.</p>
</blockquote>
<p>Start by adding the following to your Cargo.toml file:</p>
<pre><code class="language-toml">[dependencies.windows-targets]
version = "0.52"
</code></pre>
<p>Use the <code>link</code> macro to define the external functions you wish to call:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>windows_targets::link!("kernel32.dll" "system" fn SetLastError(code: u32));
windows_targets::link!("kernel32.dll" "system" fn GetLastError() -&gt; u32);
<span class="boring">}</span></code></pre></pre>
<p>Make use of any Windows APIs as needed:</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
    unsafe {
        SetLastError(1234);
        assert_eq!(GetLastError(), 1234);
    }
}</code></pre></pre>
<p>By default the <code>link</code> macro will cause the linker to use the bundled import libs. Compiling with the <code>windows_raw_dylib</code> Rust build flag will cause Cargo to skip downloading the import libs altogether and instead use <code>raw-dylib</code> to resolve imports automatically. The Rust compiler will then create the import entries directly. This works without having to change any of your code. Without the <code>windows-targets</code> crate, switching between linker and <code>raw-dylib</code> imports requires very intricate code changes. As of this writing, the <code>raw-dylib</code> feature is not yet stable.</p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="standalone-code-generation"><a class="header" href="#standalone-code-generation">Standalone code generation</a></h1>
<p>Even with a <a href="rust-getting-started/windows-or-windows-sys.html">choice between the windows and windows-sys crates</a>, some developers may prefer to use completely standalone bindings. The <a href="https://crates.io/crates/windows-bindgen">windows-bindgen</a> crate lets you generate entirely standalone bindings for Windows APIs with a single function call that you can run from a test to automate the generation of bindings. This can help to reduce your dependencies while continuing to provide a sustainable path forward for any future API requirements you might have, or just to refresh your bindings from time to time to pick up any bug fixes automatically from Microsoft.</p>
<blockquote>
<p><strong>Warning</strong>: Standalone code generation should only be used as a last resort for the most demanding scenarios. It is much simpler to use the <a href="https://crates.io/crates/windows-sys">windows-sys</a> crate and let Cargo manage this dependency. This <code>windows-sys</code> crate provides raw bindings, is heavily tested and widely used, and should not meaningfully impact your build time.</p>
</blockquote>
<p>Start by adding the following to your Cargo.toml file:</p>
<pre><code class="language-toml">[dependencies.windows-targets]
version = "0.52"

[dev-dependencies.windows-bindgen]
version = "0.52"
</code></pre>
<p>The <code>windows-bindgen</code> crate is only needed for generating bindings and is thus a dev dependency only. The <a href="https://crates.io/crates/windows-targets">windows-targets</a> crate is a dependency shared by the <code>windows</code> and <code>windows-sys</code> crates and only contains import libs for supported targets. This will ensure that you can link against any Windows API functions you may need.</p>
<p>Write a test to generate bindings as follows:</p>
<pre><pre class="playground"><code class="language-rust no_run"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>#[test]
fn bindgen() {
    let args = [
        "--out",
        "src/bindings.rs",
        "--config",
        "flatten",
        "--filter",
        "Windows.Win32.System.SystemInformation.GetTickCount",
    ];

    windows_bindgen::bindgen(args).unwrap();
}
<span class="boring">}</span></code></pre></pre>
<p>Make use of any Windows APIs as needed.</p>
<pre><code class="language-rust no_run ignore">mod bindings;

fn main() {
    unsafe {
        println!("{}", bindings::GetTickCount());
    }
}</code></pre>
<div style="break-before: page; page-break-before: always;"></div><h1 id="creating-your-first-dll-in-rust"><a class="header" href="#creating-your-first-dll-in-rust">Creating your first DLL in Rust</a></h1>
<p>As a systems programming language with similar linkage support to that of C and C++, it is quite straightforward to build a DLL in Rust. Rust does however have it's own notion of libraries that are quite different to that of C and C++, so it's just a matter of finding the right configuration to produce the desired output.</p>
<p>As with most Rust projects, you can start with Cargo and get started with a basic template but it's so simple we'll just build it by hand here to see what's involved. Let's create a directory structure as follows:</p>
<pre><code>&gt; hello_world
  Cargo.toml
  &gt; src
    lib.rs
</code></pre>
<p>Just two directories and two files. There's the <code>hello_world</code> directory that contains the project as a whole. In that directory we have a <code>Cargo.toml</code> file that contains metadata for the project or package, information needed to compile the package:</p>
<pre><code class="language-toml">[package]
name = "hello_world"
edition = "2021"

[lib]
crate-type = ["cdylib"]
</code></pre>
<p>At a minimum, the <code>[package]</code> section includes the name and Rust edition your package is compiled with.</p>
<p>Rust-only libraries don't generally include a <code>[lib]</code>  section. This is necessary when you need to specifically control how the project will be used and linked. In this case, we're using 'cdylib' that represents a dynamic system library and maps to a DLL on Windows.</p>
<p>The <code>src</code> sub directory contains the <code>lib.rs</code> Rust source file where we can add any functions that we'd like to export from the DLL. Here's a simple example:</p>
<pre><code>#[no_mangle]
extern "system" fn HelloWorld() -&gt; i32 {
    123
}
</code></pre>
<p>The <code>[no_mangle]</code> attribute just tells the compiler to disable any name mangling and use the function name verbatim as the exported identifier. The <code>extern "system"</code> function qualifier indicates the ABI or calling convention expected for the function. The "system" string represents the system-specific calling convention which generally maps to "stdcall" on Windows.</p>
<p>And that's it! You can now build the package and it will produce a DLL:</p>
<pre><code>&gt; cargo build -p hello_world
</code></pre>
<p>Cargo will drop the resulting binaries in the target directory where you can then use them from any other programming language:</p>
<pre><code>&gt; dir /b target\debug\hello_world.*
hello_world.d
hello_world.dll
hello_world.dll.exp
hello_world.dll.lib
hello_world.pdb
</code></pre>
<p>Here's a simple example in C++:</p>
<pre><code class="language-C++">#include &lt;stdint.h&gt;
#include &lt;stdio.h&gt;

extern "C" {
    int32_t __stdcall HelloWorld();
}

int main() {
    printf("%d\n", HelloWorld());
}
</code></pre>
<p>You can build it with MSVC as follows:</p>
<pre><code>cl hello_world.cpp hello_world.dll.lib
</code></pre>
<p>The dumpbin tool can be used to further inspect imports and exports.</p>
<pre><code>&gt; dumpbin /nologo /exports hello_world.dll

Dump of file hello_world.dll

File Type: DLL

  Section contains the following exports for hello_world.dll

    00000000 characteristics
    FFFFFFFF time date stamp
        0.00 version
           1 ordinal base
           1 number of functions
           1 number of names

    ordinal hint RVA      name

          1    0 00001000 HelloWorld = HelloWorld
</code></pre>
<pre><code>&gt; dumpbin /nologo /imports hello_world.exe

Dump of file hello_world.exe

File Type: EXECUTABLE IMAGE

  Section contains the following imports:

    hello_world.dll
             140017258 Import Address Table
             140021200 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                           0 HelloWorld
</code></pre>
<div style="break-before: page; page-break-before: always;"></div><h1 id="implement-a-traditional-win32-style-api"><a class="header" href="#implement-a-traditional-win32-style-api">Implement a traditional Win32-style API</a></h1>
<p>Now that we know <a href="rust-getting-started/creating-your-first-dll.html">how to create a DLL in Rust</a>, let's consider what it takes to implement a simple Win32-style API. While WinRT is generally a better choice for new  operating system APIs, Win32-style APIs continue to be important. You might need to re-implement an existing API in Rust or just need finer control of the type system or activation model for one reason or another.</p>
<p>To keep things simple but realistic, let's implement a JSON validator API. The idea is to provide a way to efficiently validate a given JSON string against a known schema. Efficiency requires that the schema is pre-compiled, so we can produce a logical JSON validator object that may be created and freed separately from the process of validating the JSON string. You can imagine a hypothetical Win32-style API looking like this:</p>
<pre><code class="language-C++">HRESULT __stdcall CreateJsonValidator(char const* schema, size_t schema_len, uintptr_t* handle);

HRESULT __stdcall ValidateJson(uintptr_t handle, char const* value, size_t value_len, char** sanitized_value, size_t* sanitized_value_len);

void __stdcall CloseJsonValidator(uintptr_t handle);
</code></pre>
<p>The <code>CreateJsonValidator</code> function should compile the schema and make it available through the returned <code>handle</code>.</p>
<p>The handle can then be passed to the <code>ValidateJson</code> function to perform the validation. The function can optionally return a sanitized version of the JSON value.</p>
<p>The JSON validator handle can later be freed using the <code>CloseJsonValidator</code> function, causing any memory occupied by the validator "object" to be freed.</p>
<p>Both creation and validation can fail, so those functions return an <code>HRESULT</code>, with rich error information being available via the <code>GetErrorInfo</code> function.</p>
<p>Let's use the <code>windows</code> crate for basic Windows error handling and type support. The popular <code>serde_json</code> crate will be used for parsing JSON strings. Unfortunately, it doesn't provide schema validation. A quick online search reveals the <code>jsonschema</code> crate seems to be the main or only game in town. It will do for this example. The focus here is not really on the particular implementation as much as the process of building such an API in Rust generally.</p>
<p>Given these dependencies and what we learned about creating a DLL in Rust, here's what the project's <code>Cargo.toml</code> file should look like:</p>
<pre><code class="language-toml">[package]
name = "json_validator"
edition = "2021"

[lib]
crate-type = ["cdylib"]

[dependencies]
jsonschema = "0.17"
serde_json = "1.0"

[dependencies.windows]
version = "0.52"
features = [
    "Win32_Foundation",
    "Win32_System_Com",
]
</code></pre>
<p>We can employ a <code>use</code> declaration to make things a little easier for ourselves:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use jsonschema::JSONSchema;
use windows::{core::*, Win32::Foundation::*, Win32::System::Com::*};
<span class="boring">}</span></code></pre></pre>
<p>And let's begin with the <code>CreateJsonValidator</code> API function. Here's how the C++ declaration might look in Rust:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>#[no_mangle]
unsafe extern "system" fn CreateJsonValidator(
    schema: *const u8,
    schema_len: usize,
    handle: *mut usize,
) -&gt; HRESULT {
    create_validator(schema, schema_len, handle).into()
}
<span class="boring">}</span></code></pre></pre>
<p>Nothing too exciting here. We're just using the definition of <code>HRESULT</code> from the <code>windows</code> crate. The implementation calls a different <code>create_validator</code> function for its implementaion. We'll do this so that we can use the syntactic convenience of the standard <a href="https://doc.rust-lang.org/stable/std/result/index.html">Result</a> type for error propagation. The specialization of <code>Result</code> provided by the <code>windows</code> crate further supports turning a <code>Result</code> into an <code>HRESULT</code> while discharging its rich error information to the caller. That's what the trailing <code>into()</code> is used for.</p>
<p>The <code>create_validator</code> function looks as follows:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>unsafe fn create_validator(schema: *const u8, schema_len: usize, handle: *mut usize) -&gt; Result&lt;()&gt; {
    // ...

    Ok(())
}
<span class="boring">}</span></code></pre></pre>
<p>As you can see, it carries the exact same parameters and simply switches out the <code>HRESULT</code> for a <code>Result</code> returning the <a href="https://doc.rust-lang.org/stable/std/primitive.unit.html">unit type</a>, or nothing other than success or error information.</p>
<p>First up, we need to parse the provided schema using <code>serde_json</code>. Since we need to parse JSON in a couple spots, we'll just drop this in a reusable helper function:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>unsafe fn json_from_raw_parts(value: *const u8, value_len: usize) -&gt; Result&lt;serde_json::Value&gt; {
    if value.is_null() {
        return Err(E_POINTER.into());
    }

    let value = std::slice::from_raw_parts(value, value_len);

    let value =
        std::str::from_utf8(value).map_err(|_| Error::from(ERROR_NO_UNICODE_TRANSLATION))?;

    serde_json::from_str(value).map_err(|error| Error::new(E_INVALIDARG, format!("{error}").into()))
}
<span class="boring">}</span></code></pre></pre>
<p>The <code>json_from_raw_parts</code> function starts by checking that the pointer to a UTF-8 string is not null, return <code>E_POINTER</code> in such cases. We can then turn the pointer and length into a Rust slice and from there a string slice, ensuring that it is in fact a valid UTF-8 string. Finally, we call out to <code>serde_json</code> to turn the string into a JSON value for further processing.</p>
<p>Now that we can parse JSON, completing the <code>create_validator</code> function is relatively straightforward:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>unsafe fn create_validator(schema: *const u8, schema_len: usize, handle: *mut usize) -&gt; Result&lt;()&gt; {
    let schema = json_from_raw_parts(schema, schema_len)?;

    let compiled = JSONSchema::compile(&amp;schema)
        .map_err(|error| Error::new(E_INVALIDARG, error.to_string().into()))?;

    if handle.is_null() {
        return Err(E_POINTER.into());
    }

    *handle = Box::into_raw(Box::new(compiled)) as usize;

    Ok(())
}
<span class="boring">}</span></code></pre></pre>
<p>The JSON value, in this case the JSON schema, is passed to <code>JSONSchema::compile</code> to produce the compiled representation. While the value is known to be JSON at this point, it may not in fact be a valid JSON schema. In such cases, we'll return <code>E_INVALIDARG</code> and include the error message from the JSON schema compiler to aid in debugging. Finally, provided the handle pointer is not null, we can go ahead and box the compiled representation and return it as the "handle".</p>
<p>Now let's move on to the <code>CloseJsonValidator</code> function since it's closely related to the boxing code above. Boxing just means to move the value on to the heap. The <code>CloseJsonValidator</code> function therefore needs to "drop" the object and free that heap allocation:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>#[no_mangle]
unsafe extern "system" fn CloseJsonValidator(handle: usize) {
    if handle != 0 {
        _ = Box::from_raw(handle as *mut JSONSchema);
    }
}
<span class="boring">}</span></code></pre></pre>
<p>We can add a little safeguard if a zero handle is provided. This is a pretty standard convenience feature to simplify generic programming for callers, but a caller can generally avoid the indirection cost of calling <code>CloseJsonValidator</code> if they know the handle is zero.</p>
<p>Finally, let's consider the <code>ValidateJson</code> function's implementation:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>#[no_mangle]
unsafe extern "system" fn ValidateJson(
    handle: usize,
    value: *const u8,
    value_len: usize,
    sanitized_value: *mut *mut u8,
    sanitized_value_len: *mut usize,
) -&gt; HRESULT {
    validate(
        handle,
        value,
        value_len,
        sanitized_value,
        sanitized_value_len,
    )
    .into()
}
<span class="boring">}</span></code></pre></pre>
<p>Here again the implementation forwards to a <code>Result</code>-returning function for convenience:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>unsafe fn validate(
    handle: usize,
    value: *const u8,
    value_len: usize,
    sanitized_value: *mut *mut u8,
    sanitized_value_len: *mut usize,
) -&gt; Result&lt;()&gt; {
    // ...
}
<span class="boring">}</span></code></pre></pre>
<p>First up, we need to ensure that we even have a valid handle, before transforming it into a <code>JSONSchema</code> object reference:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>if handle == 0 {
    return Err(E_HANDLE.into());
}

let schema = &amp;*(handle as *const JSONSchema);
<span class="boring">}</span></code></pre></pre>
<p>This looks a bit tricky but we're just turning the opaque handle into a <code>JSONSchema</code> pointer and then returning a reference to avoid taking ownership of it.</p>
<p>Next, we need to parse the provided JSON value:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let value = json_from_raw_parts(value, value_len)?;
<span class="boring">}</span></code></pre></pre>
<p>Here again we use the handy <code>json_from_raw_parts</code> helper function and allow error propagation to be handled automatically via the <code>?</code> operator.</p>
<p>At this point we can perform schema validation, optionally returning a sanitized copy of the JSON value:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>if schema.is_valid(&amp;value) {
    if !sanitized_value.is_null() &amp;&amp; !sanitized_value_len.is_null() {
        let value = value.to_string();

        *sanitized_value = CoTaskMemAlloc(value.len()) as _;

        if (*sanitized_value).is_null() {
            return Err(E_OUTOFMEMORY.into());
        }

        (*sanitized_value).copy_from(value.as_ptr(), value.len());
        *sanitized_value_len = value.len();
    }

    Ok(())
} else {
    // ...
}
<span class="boring">}</span></code></pre></pre>
<p>Assuming the JSON value checks out against the compiled schema, we see whether the caller provided pointers to return a sanitized copy of the JSON value. In that case, we call <code>to_string</code> to return a string representation straight from the JSON parser, use <code>CoTaskMemAlloc</code> to allocate a buffer to return to the caller and copy the resulting UTF-8 string into this buffer.</p>
<p>If things don't go well, we can get the compiled schema to produce a handy error message before returning <code>E_INVALIDARG</code> to the caller:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let mut message = String::new();

if let Some(error) = schema.validate(&amp;value).unwrap_err().next() {
    message = error.to_string();
}

Err(Error::new(E_INVALIDARG, message.into()))
<span class="boring">}</span></code></pre></pre>
<p>The <code>validate</code> method returns a collection of errors. We'll just return the first for simplicity.</p>
<p>And that's it! Your first Win32-style API in Rust. You can <a href="https://github.com/microsoft/windows-rs/tree/master/crates/samples/components/json_validator">find the complete example here</a>.</p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="working-with-strings-in-the-windows-crate"><a class="header" href="#working-with-strings-in-the-windows-crate">Working with strings in the windows crate</a></h1>
<p>There are several string types in the Windows APIs including:</p>
<ul>
<li><code>PSTR</code>/<code>PCSTR</code>: A pointer to a null terminated string consisting of chars (u8). Strings should be encoded using the current thread's code page. A 'C' indicates a "constant" (read-only) string.</li>
<li><code>PWSTR</code>/<code>PCWSTR</code>: A pointer to a null terminated string consisting of 'wide chars' (u16), encoded using UTF-16.</li>
<li><code>BSTR</code>: A binary string commonly used in COM/OLE functions. It consists of u16 characters followed by a null terminator. The strings have their length prepended before the pointer, and some functions will use them to pass arbitrary binary data (including data containing nulls), relying on the prefix rather than the terminator. However, they <em>usually</em> can be used as normal, null-terminated wide strings.</li>
<li><code>HSTRING</code>: A handle to a Windows Runtime string. HSTRINGS are UTF-16 and immutable.</li>
</ul>
<p>Note that you can pass BSTR or HSTRING to functions expecting a PCWSTR.</p>
<p>Unfortunately, none of these types match Rust types one-to-one. However, we can use the <code>windows-strings</code> crate to help us.</p>
<h2 id="types-of-api-functions-narrow-or-wide"><a class="header" href="#types-of-api-functions-narrow-or-wide">Types of API Functions (Narrow or Wide)</a></h2>
<p>The Win32 API divides string functions into their "narrow" version (ending in 'A', like <code>MessageBoxA</code>), and their "wide" version (ending in 'W', like <code>MessageBoxW</code>). Narrow versions of the API expect u8 byte strings, encoded using the current thread's code page, while wide versions expect UTF-16.</p>
<p>As a general recommendation, you should prefer wide versions; it's much easier to convert between Rust's UTF-8 strings and Windows' UTF-16.</p>
<h2 id="calling-apis-that-consume-strings"><a class="header" href="#calling-apis-that-consume-strings">Calling APIs that Consume Strings</a></h2>
<p>Let's look at an example using the simple <a href="https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/UI/WindowsAndMessaging/fn.MessageBoxW.html"><code>MessageBox</code> function</a>, which displays a pop up dialog box. We'll use the wide version (<code>MessageBoxW</code>) for this example.</p>
<p>If you want to call a Windows API using a string literal, the <code>windows-strings</code> crate has macros to generate Windows strings from string literals:</p>
<ul>
<li><code>h!</code> generates an HSTRING from a string literal, adding a null terminator and converting to UTF-16.</li>
<li><code>w!</code> does the same, but generates a PCWSTR instead of an HSTRING.</li>
<li><code>s!</code> generates a PCSTR with a null terminator. <em>Caution: this does not do any conversions, it simply adds a null terminator.</em></li>
</ul>
<p>If we wanted to call the message box we could use the windows crate with the <code>Win32_UI_WindowsAndMessaging</code> feature, and call:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>// use string literals when calling a message box. 
let text = h!("Hello from rust!");
let caption = h!("From Rust");

unsafe {
    // call the MessageBox function and return MESSAGEBOX_RESULT
    UI::WindowsAndMessaging::MessageBoxW(None, 
        text, 
        caption,
        UI::WindowsAndMessaging::MESSAGEBOX_STYLE(0) // message box OK
    )
}
<span class="boring">}</span></code></pre></pre>
<p>This works, but what if we wanted to call the same function with a Rust string? That gets slightly more complicated. We could manually convert to a UTF-16 series of bytes, and add the null terminator ourselves, like this:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>// this works for any &amp;str, not just literals
let text = "I am a message to display!";
let caption = "Message from Rust!";

// convert our text and caption to UTF-16 bytes,
// add null terminators using chain, and then collect
// the result into a vec
let text = text.encode_utf16()
    .chain(iter::once(0u16))
    .collect::&lt;Vec&lt;u16&gt;&gt;();
let caption = caption.encode_utf16()
    .chain(iter::once(0u16))
    .collect::&lt;Vec&lt;u16&gt;&gt;();

// call the API, wrapping our vec pointer in a PCWSTR struct.
unsafe {
    UI::WindowsAndMessaging::MessageBoxW(None, 
        PCWSTR(text.as_ptr()), 
        PCWSTR(caption.as_ptr()),
        UI::WindowsAndMessaging::MESSAGEBOX_STYLE(0) // message box OK
    )
}
<span class="boring">}</span></code></pre></pre>
<p>However, this is cumbersome - we can use the convenience features in the <code>windows-strings</code> crate to make this much simpler by converting the Rust strings to HSTRING.</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let text = "I am a message to display!";
let caption = "Message from Rust!";

// convert our strings into UTF-16 
// this incurrs a performance cost because there is a copy + conversion
// from the standard rust utf-8 string. 

// we are using HSTRING, which is an immutable UTF-16 string
// in the windows-strings crate. It can be generated from a standard
// rust string, and it can be used in place of a PCWSTR anywhere in the
// windows API. 

unsafe {
    UI::WindowsAndMessaging::MessageBoxW(None, 
        &amp;HSTRING::from(text), 
        &amp;HSTRING::from(caption),
        UI::WindowsAndMessaging::MESSAGEBOX_STYLE(0) // message box OK
    )
    }
<span class="boring">}</span></code></pre></pre>
<p>This is much more ergonomic - it handles the null termination and UTF-16 conversion for you.</p>
<h2 id="calling-apis-that-generate-strings"><a class="header" href="#calling-apis-that-generate-strings">Calling APIs that Generate Strings</a></h2>
<p>Windows APIs that generate strings usually require a two-step call. The first time you call the API, you pass in a NULL pointer for the string buffer, and retrieve the length of the string to be generated.</p>
<p>This allows you to allocate the buffer accordingly, and then call the function again with an appopriately sized buffer.</p>
<p>For this example, we'll use the <a href="https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/System/WindowsProgramming/fn.GetComputerNameW.html"><code>GetComputerNameW</code> function</a>. This requires the <code>Win32_System_WindowsProgramming</code> feature from the windows crate.</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let mut buff_len = 0u32;

unsafe {
    // this function will return an error code because it
    // did not actually write the string. This is normal.
    let e = GetComputerNameW(None, &amp;mut buff_len).unwrap_err();
    debug_assert_eq!(e.code(), HRESULT::from(ERROR_BUFFER_OVERFLOW));
}

// buff len now has the length of the string (in UTF-16 characters)
// the function would like to write. This *does include* the
// null terminator. Let's create a vector buffer and feed that to the function.
let mut buffer = Vec::&lt;u16&gt;::with_capacity(buff_len as usize);

unsafe {
    WindowsProgramming::GetComputerNameW(
        Some(PWSTR(buffer.as_mut_ptr())), 
        &amp;mut buff_len).unwrap();

    // set the vector length
    // buff_len now includes the size, which *does not include* the null terminator.
    // let's set the length to just before the terminator so we don't have to worry
    // about it in later conversions.
    buffer.set_len(buff_len);
}

// we can now convert this to a valid Rust string
// omitting the null terminator
String::from_utf16_lossy(&amp;buffer)
<span class="boring">}</span></code></pre></pre>
<p>It's worth calling out how the length parameter works. For GetComputerNameW:</p>
<ul>
<li>On input, it represents the size of the buffer <em>including the null terminator</em> in wchar.</li>
<li>If the function returns a buffer overflow, the length parameter returned is how
large a buffer it needs <em>including the null terminator</em> in wchars.</li>
<li>If the function successfully wrote to the buffer, the length is the number
of wchars written <em>not including the null terminator.</em></li>
</ul>
<p><a href="https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getcomputernamew">This behavior is documented in the function's documentation</a> - when using the Windows API, be careful and check what the function expectes with respect to null terminators.</p>
<p>Regardless, this does work, but we can do better. Computer names can only be up to <code>MAX_COMPUTERNAME_LENGTH</code> which is a meager 16 characters. We can avoid a heap allocation here and just use arrays, since we know our buffer length at compile time.</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>// avoid the heap allocation since we already know how big this 
// buffer needs to be at compile time. 

let mut name = [0u16; MAX_COMPUTERNAME_LENGTH as usize + 1];
let mut len = name.len() as u32;

// we can also skip the two-step call, since we know our buffer
// is already larger than any possible computer name

unsafe {
    GetComputerNameW(
        Some(PWSTR(name.as_mut_ptr())), 
        &amp;mut len)
        .unwrap();
}

// the function writes to len with the number of 
// UTF-16 characters in the string. We can use this
// to slice the buffer. 
String::from_utf16_lossy(&amp;name[..len as usize])
<span class="boring">}</span></code></pre></pre>
<p>However, if we don't mind the heap allocation (and a few extra system calls), there is a more ergonomic option. The <code>windows-strings</code> crate includes <code>HStringBuilder</code> that we can use in place of the array. This gives us much easier conversions.</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>// pre-allocate a HSTRING buffer on the heap
// (you do not need to add one to len for the null terminator,
// the hstring builder will handle that automatically)

let mut buffer = HStringBuilder::new(
    MAX_COMPUTERNAME_LENGTH as usize);

let mut len = buffer.len() as u32 + 1;

unsafe {
    GetComputerNameW(
        Some(PWSTR(buffer.as_mut_ptr())), 
        &amp;mut len).unwrap();
}

// we can now generate a valid HSTRING from the HStringBuilder
let buffer = HSTRING::from(buffer);

// and we can now return a rust string from the HSTRING:
buffer.to_string_lossy()
<span class="boring">}</span></code></pre></pre>
<p>If you need to work with UTF-16 strings directly, consider using the <code>widestring</code> crate, which is UTF-16 aware. This will enable you to push/pop/append elements without having to convert the string to a native rust UTF-8 string. For completeness, here's an example of returning a widestring, and appending some exclaimation marks.</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>// for this example, we'll just use an array again

let mut name = [0u16; MAX_COMPUTERNAME_LENGTH as usize + 1];
let mut len = name.len() as u32;

unsafe {
    GetComputerNameW(
        Some(PWSTR(name.as_mut_ptr())), 
        &amp;mut len)
        .unwrap();
}

// we can make a UTF16Str slice directly from the buffer,
// without needing to do any copy. This will error if the buffer
// isn't valid UTF-16. 
let wstr = Utf16Str::from_slice(&amp;name[..len as usize])
    .unwrap();

// this can be displayed as is.
println!("Computer name is {}", wstr);

// we can also transfer it into owned string, which can
// be appended or modified. 
let mut wstring = Utf16String::from(wstr);

// let's append another string. We'll use a macro to avoid
// any UTF conversion at runtime. 
wstring = wstring + utf16str!("!!!");
<span class="boring">}</span></code></pre></pre>

                    </main>

                    <nav class="nav-wrapper" aria-label="Page navigation">
                        <!-- Mobile navigation buttons -->


                        <div style="clear: both"></div>
                    </nav>
                </div>
            </div>

            <nav class="nav-wide-wrapper" aria-label="Page navigation">

            </nav>

        </div>




        <script>
            window.playground_copyable = true;
        </script>


        <script src="elasticlunr.min.js"></script>
        <script src="mark.min.js"></script>
        <script src="searcher.js"></script>

        <script src="clipboard.min.js"></script>
        <script src="highlight.js"></script>
        <script src="book.js"></script>

        <!-- Custom JS scripts -->

        <script>
        window.addEventListener('load', function() {
            window.setTimeout(window.print, 100);
        });
        </script>

    </div>
    </body>
</html>
